'''
Created on Nov 23, 2010

@author: namikata
'''

import gameobjects
from gameobjects.vector2 import Vector2
from game.base.Resources import Resources
from game.base.GameEntity import KCLASS_PLAYER, KCLASS_UI, KSCLASS_UIPLAYER
import pyglet

class World(object):

    entities = {} # Store all the entities
    menus = {}
    messages = {}
    render_batch = pyglet.graphics.Batch()
    entity_id = 0 # Last entity id assigned
    fillcolor = (0, 255, 0)
    fillimage = None
    paused = False
    resources = None
    bounds = None
    show_ui = True
    energy_pool = 20000
    energy_per_second = 200
    players = {}
    ui_elements = {}
    time_scale = 1.
  
    def __init__(self):
        self.entities = {} # Store all the entities
        self.menus = {}
        self.messages = {}
        self.entity_id = 0 # Last entity id assigned
        self.fillcolor = (0, 255, 0)
        self.fillimage = None
        self.paused = False
        self.resources = None
        self.bounds = None
        self.show_ui = True
        self.energy_pool = 20000
        self.energy_per_second = 200
        self.players = {}
        self.time_scale = 1.
        
    def load_resources(self,resFile):
        self.resources = Resources(resFile)

    def add_entity(self, entity):
        """Stores the entity then advances the current id"""
        self.entities[self.entity_id] = entity
        entity.id = self.entity_id
        entity.sprite.batch = self.render_batch
        self.entity_id += 1
        if entity.objclass == KCLASS_PLAYER:
            self.players[entity.id] = entity
        elif entity.objclass == KCLASS_UI:
            self.ui_elements[entity.id] = entity
    
    def add_menu(self, entity):
        pass
        #"""Stores the entity then advances the current id"""
        #if entity.objclass != KCLASS_UI:
        #    return
        #if entity.objsclass != KSCLASS_UIMENU:
        #    return
         
        #self.menus[self.entity_id] = entity
        #entity.id = self.entity_id
        #self.entity_id += 1
    
    def add_message(self, entity):
        pass
        #"""Stores the entity then advances the current id"""
        #if entity.objclass != KCLASS_UI:
        #    return
        #if entity.objsclass != KSCLASS_UIMESSAGE:
        #    return
        #
        #self.messages[self.entity_id] = entity
        #entity.id = self.entity_id
        #self.entity_id += 1

    def remove_entity(self, entity):
        del self.entities[entity.id]
            
    def get(self, entity_id):
        """Find the entity, given its id (or None if it is not found)"""
        if entity_id in self.entities:
            return self.entities[entity_id]
        else:
            return None
        
    def get_by_name(self,entity_name):
        """Find the entity, given its name (or None if it is not found)"""
        found = None
        for entity in self.entities.itervalues():
            if entity_name == entity.name:
                found = entity
                break
        
        return found
            
    def get_by_class(self,objclass = None,objsclass = None):
        pass
        """Get all entities of a given class and subclass"""
        if not objclass:
            return self.entities.values()
        
        found = []
        for entity in self.entities.itervalues():
            if entity.objclass == objclass:
                if not objsclass:
                    found.append(entity)
                else:
                    if entity.objsclass == objsclass:
                        found.append(entity)
                        
        return found
        
    def update(self, time_elapsed,keyboard,mouse):
        pass
        """Updates every entity in the world"""       
        time_passed_seconds = time_elapsed if not self.paused else 0.
        
        #get energy that will be shared
        if self.energy_pool > 0 and len(self.players) > 0:
            energy = min(self.energy_per_second*time_elapsed, self.energy_pool)
            self.energy_pool -= energy
            energy = energy/len(self.players)
        
        for entity in list(self.entities.itervalues()):
            if entity.objclass == KCLASS_PLAYER:
                self.energy_pool += entity.armory.add_energy(energy)
            if entity.destroy:
                self.remove_entity(entity)
                entity.sprite.batch = None
                self.energy_pool += entity.data.energy
            else:
                entity.update(float(time_passed_seconds),keyboard,mouse)                
        for entity in list(self.menus.itervalues()):
            if entity.destroy:
                self.remove_entity(entity)
            else:
                entity.update(time_passed_seconds,keyboard,mouse)
        for entity in list(self.messages.itervalues()):
            if entity.destroy:
                self.remove_entity(entity)
            else:
                entity.update(time_passed_seconds,keyboard,mouse)
            
    def render(self):
        self.render_batch.draw()
        """Draw the background and all the entities"""
        
        #surface.fill(self.fillcolor)
        #if self.fillimage:
        #    surface.blit(self.fillimage, (0, 0))
            
        for entity in self.entities.values():
            entity.render()
        for entity in self.menus.values():
            entity.render()
        for entity in self.messages.values():
            entity.render()

    def toggle_ui(self):
        self.show_ui = not self.show_ui
        for entity in self.ui_elements.itervalues():
            if self.show_ui:
                entity.sprite.batch = self.render_batch
            else:
                entity.sprite.batch = None

    def get_close_entities(self, objclass, objsclass, location, range=100.):
        pass
        """Find entities within range of a location"""
        location = Vector2(*location)
        entities = {}
        for entity in self.entities.values():
            if objclass != None:
                if entity.objclass != objclass:
                    continue
                else:
                    if objsclass:
                        if objsclass != entity.objsclass:
                            continue
            distance = location.get_distance_to(entity.location)
            if distance < range:
                entities[entity.id] = entity

        return entities if len(entities>0) else None
        
    def is_inside_bounds(self, point):
        point = Vector2(*point)
        if point.x < self.bounds[0].x or\
        point.x > self.bounds[1].x or\
        point.y < self.bounds[0].y or\
        point.y > self.bounds[1].y:
            return False
        else:
            return True